﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NumericValueValidator.cs" company="">
//   
// </copyright>
// <summary>
//   The numeric value validator.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Skymate.Runtime.Validation
{
    using System;

    using Skymate.Extensions;

    /// <summary>
    ///     The numeric value validator.
    /// </summary>
    [Serializable]
    [Validator("NUMERIC")]
    public class NumericValueValidator : ValueValidatorBase
    {
        /// <summary>
        ///     Initializes a new instance of the <see cref="NumericValueValidator" /> class.
        /// </summary>
        public NumericValueValidator()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="NumericValueValidator"/> class.
        /// </summary>
        /// <param name="minValue">
        /// The min value.
        /// </param>
        /// <param name="maxValue">
        /// The max value.
        /// </param>
        public NumericValueValidator(int minValue = int.MinValue, int maxValue = int.MaxValue)
        {
            this.MinValue = minValue;
            this.MaxValue = maxValue;
        }

        /// <summary>
        ///     Gets or sets the min value.
        /// </summary>
        public int MinValue
        {
            get
            {
                return (this["MinValue"] ?? "0").To<int>();
            }

            set
            {
                this["MinValue"] = value;
            }
        }

        /// <summary>
        ///     Gets or sets the max value.
        /// </summary>
        public int MaxValue
        {
            get
            {
                return (this["MaxValue"] ?? "0").To<int>();
            }

            set
            {
                this["MaxValue"] = value;
            }
        }

        /// <summary>
        /// The is valid.
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        public override bool IsValid(object value)
        {
            if (value == null)
            {
                return false;
            }

            if (value is int)
            {
                return this.IsValidInternal((int)value);
            }

            if (value is string)
            {
                int intValue;
                if (int.TryParse(value as string, out intValue))
                {
                    return this.IsValidInternal(intValue);
                }
            }

            return false;
        }

        /// <summary>
        /// The is valid internal.
        /// </summary>
        /// <param name="value">
        /// The value.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        protected virtual bool IsValidInternal(int value)
        {
            return value.IsBetween(this.MinValue, this.MaxValue);
        }
    }
}